package org.vz;

import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.JWSAlgorithm;
import com.nimbusds.jose.jwk.source.JWKSource;
import com.nimbusds.jose.jwk.source.RemoteJWKSet;
import com.nimbusds.jose.proc.BadJOSEException;
import com.nimbusds.jose.proc.JWSKeySelector;
import com.nimbusds.jose.proc.JWSVerificationKeySelector;
import com.nimbusds.jose.proc.SecurityContext;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.proc.ConfigurableJWTProcessor;
import com.nimbusds.jwt.proc.DefaultJWTProcessor;
import org.dmfs.httpessentials.client.HttpRequestExecutor;
import org.dmfs.httpessentials.exceptions.ProtocolError;
import org.dmfs.httpessentials.exceptions.ProtocolException;
import org.dmfs.httpessentials.httpurlconnection.HttpUrlConnectionExecutor;
import org.dmfs.oauth2.client.*;
import org.dmfs.oauth2.client.grants.ResourceOwnerPasswordGrant;
import org.dmfs.oauth2.client.scope.EmptyScope;
import org.dmfs.rfc3986.encoding.Precoded;
import org.dmfs.rfc3986.uris.LazyUri;
import org.dmfs.rfc5545.Duration;

import java.io.IOException;
import java.net.URI;
import java.net.URL;
import java.text.ParseException;

/**
 * 描述: 客户端以密码模式进行授权Resource Owner Password Credentials Grant
 *
 * @param
 * @author chenhj
 * @version 1.0.0
 * @return
 */
public class Oauth2Pwd {
	public static void main(String[] args) throws ProtocolException, ProtocolError, IOException, ParseException, JOSEException, BadJOSEException {
		HttpRequestExecutor executor = new HttpUrlConnectionExecutor();


		OAuth2AuthorizationProvider provider = new BasicOAuth2AuthorizationProvider(
			URI.create("http://dhis2.cn:31000/connect/authorize"),
			URI.create("http://dhis2.cn:31000/connect/token"),
			new Duration(1, 0, 3600) /* default expiration time in case the server doesn't return any */);

		OAuth2ClientCredentials credentials = new BasicOAuth2ClientCredentials(
			"pwd_test", "7851a8518e264aef8f78b75fba6f7831");

		org.dmfs.rfc3986.Uri redirectUrl =  new LazyUri(new Precoded("http://192.168.120.219:2182/hapi-fhir-jpaserver-example"));

		OAuth2Client client = new BasicOAuth2Client(
			provider,
			credentials,//不能为空
			redirectUrl /* Redirect URL */);
		OAuth2AccessToken token = new ResourceOwnerPasswordGrant(client, new EmptyScope(),"chj","123456").accessToken(executor);

		String realToken = token.accessToken().toString();
		System.out.println("获取的token为:\n"+realToken);

		/*********************用nimbus-jose-jwt进行签名验证***************/

// Set up a JWT processor to parse the tokens and then check their signature
// and validity time window (bounded by the "iat", "nbf" and "exp" claims)
		ConfigurableJWTProcessor jwtProcessor = new DefaultJWTProcessor();

// The public RSA keys to validate the signatures will be sourced from the
// OAuth 2.0 server's JWK set, published at a well-known URL. The RemoteJWKSet
// object caches the retrieved keys to speed up subsequent look-ups and can
// also gracefully handle key-rollover
		JWKSource keySource = new RemoteJWKSet(new URL("http://dhis2.cn:31000/.well-known/openid-configuration/jwks"));//获取public_key


		// The expected JWS algorithm of the access tokens (agreed out-of-band)
		JWSAlgorithm expectedJWSAlg = JWSAlgorithm.RS256;

// Configure the JWT processor with a key selector to feed matching public
// RSA keys sourced from the JWK set URL
		JWSKeySelector keySelector = new JWSVerificationKeySelector(expectedJWSAlg, keySource);
		jwtProcessor.setJWSKeySelector(keySelector);

		// Process the token
		SecurityContext ctx = null; // optional context parameter, not required here
		JWTClaimsSet claimsSet = jwtProcessor.process(realToken, ctx);
// Print out the token claims set
		System.out.println(claimsSet.toJSONObject());

		/*********************用nimbus-jose-jwt进行签名验证***************/
	}
}
